﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OWANotifier.Properties;
using System.ComponentModel;
using System.Net;
using System.Windows.Forms;
using System.Security.Principal;

namespace OWANotifier
{
    public class Notifier
    {

        public event EventHandler NewMessage;

        public event EventHandler PollStarted;

        public event EventHandler PollFinished;

        public enum NotifierStatus
        {
            Online,
            Offline,
            Polling,
        }

        public NotifierStatus Status { get; set; }

        public List<Message> Messages { get; set; }

        public Exception LastError { get; set; }

        public string Password { get; set; }

        private static Notifier instance;

        public static Notifier Instance
        {
            get
            {
                if (instance == null)
                    instance = new Notifier();
                return Notifier.instance;
            }
        }

        internal Notifier()
        {
            LastError = null;
            Status = NotifierStatus.Online;
            Messages = new List<Message>();

            if (!string.IsNullOrEmpty(Settings.Default.Password))
            {
                Password = TercerPlaneta.Lib.StringConfig.ToString(Settings.Default.Password);
            }

        }











        public bool Poll()
        {
            if (Status == NotifierStatus.Online)
            {

                LastError = null;
                int prevMessageCount = Messages.Count;
                Message prevLastMessage = null;
                if (Messages.Count > 0) prevLastMessage = Messages[0];
                Messages.Clear();
                Status = NotifierStatus.Polling;

                try
                {


                    if (Password == null)
                    {
                        using (LoginForm lf = new LoginForm
                        {
                            Username = Settings.Default.Username,
                            Server = new Uri(Settings.Default.UnreadMessagesUri).Host,
                            Password = "",
                            RememberPassword = false,
                            IntegratedSecurity = Settings.Default.IntegratedSecurity
                        })
                        {

                            if (lf.ShowDialog() == DialogResult.OK)
                            {
                                Settings.Default.IntegratedSecurity = lf.IntegratedSecurity;
                                if (lf.IntegratedSecurity)
                                {
                                    Settings.Default.Username = WindowsIdentity.GetCurrent().Name;
                                    Password = "{IntegratedSecurity}";
                                    Settings.Default.Password = Password;
                                }
                                else
                                {
                                    Password = lf.Password;
                                    Settings.Default.Username = lf.Username;
                                    if (lf.RememberPassword)
                                        Settings.Default.Password = TercerPlaneta.Lib.StringConfig.ToConfig(Password);
                                }
                                Settings.Default.Save();
                            }
                            else
                            {
                                Password = null;
                                Status = NotifierStatus.Offline;
                            }
                        }
                    }

                    if ((Password != null) && (Status == NotifierStatus.Polling))
                    {

                        if (PollStarted != null)
                            PollStarted(this, EventArgs.Empty);
                        try
                        {
                            Messages.AddRange(new OWAMessageListRequest
                                {
                                    X509CertificateFilename = Settings.Default.X509CertificateFilename,
                                    Uri = new Uri(string.Format(Settings.Default.UnreadMessagesUri, OWAMessageListRequest.GetUser(Settings.Default.Username))),
                                    User = Settings.Default.Username,
                                    Password = Password,
                                    IntegratedSecurity = Settings.Default.IntegratedSecurity,
                                }.Request());


                            if ((Messages.Count > 0) &&
                                ((prevMessageCount < Messages.Count) ||
                                 (prevLastMessage.Received < Messages[0].Received)))
                                if (NewMessage != null)
                                {
                                    try
                                    {
                                        NewMessage(this, EventArgs.Empty);
                                    }
                                    catch { }
                                }


                        }
                        catch (Exception ex)
                        {
                            LastError = ex;
                            Messages.Clear();

                            if (ex as WebException != null)
                            {
                                switch (((WebException)ex).Status)
                                {
                                    case WebExceptionStatus.ProtocolError:
                                        if (!Settings.Default.IntegratedSecurity)
                                            Password = null;
                                        break;
                                    default:
                                        break;
                                }
                            }

                            return false;

                        }
                        finally
                        {
                            if (PollFinished != null)
                                PollFinished(this, EventArgs.Empty);
                        }
                    }
                    else
                    {
                        return false;
                    }

                }
                catch (Exception ex)
                {
                    LastError = ex;
                    return false;
                }
                finally
                {
                    if (Status == NotifierStatus.Polling)
                        Status = NotifierStatus.Online;
                }
                return true;
            }
            return false;
        }
    }
}
